package chouxiang.rpc;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by tiang on 2018/7/20.
 * 服务提供者
 */
public class Provider {
    // 存放暴露的接口
    private List<Object> objList = new ArrayList<>();
    // 注册接口
    public void register(Object obj){
        objList.add(obj);
    }
    // 服务端口号
    private int port;
    public Provider(int port){
        this.port = port;
    }
    // 启动服务
    public void start() throws IOException {
        ServerSocket server = new ServerSocket(port);
        while(true){
            Socket client = server.accept();
            new Thread(()->{
                ObjectInputStream reader = null;
                ObjectOutputStream writer = null;
                try {
                    reader = new ObjectInputStream(client.getInputStream());
//                    获取目标类型
                    Class<?> aimClass = (Class<?>) reader.readObject();
//                    获取目标类型对应的对象
                    Object aimObj = findAimClass(aimClass);
                    System.out.println("已找到目标对象");
                    // 获取方法名
                    String aimMethodName = (String) reader.readObject();
                    // 方法的参数类型列表
                    Class[] parameterTypes = (Class[]) reader.readObject();
                    // 获取目标方法
                    Method aimMethod = aimObj.getClass().getMethod(aimMethodName, parameterTypes);
                    System.out.println("已获取目标方法");
                    // 获取方法的参数信息
                    Object[] args = (Object[]) reader.readObject();
                    // 执行方法
                    Object result = aimMethod.invoke(aimObj, args);
                    System.out.println("目标方法执行完毕");
                    writer = new ObjectOutputStream(client.getOutputStream());
                    writer.writeObject(result);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        reader.close();
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }).start();
        }
    }
    // 查找指定类型的对象
    private Object findAimClass(Class aimClass){
        for(Object obj : objList){
            if(aimClass.isAssignableFrom(obj.getClass())){
                return obj;
            }
        }
        return null;
    }
}
